/*
 * This file handles the GameOfNim server class.
 * It uses a linked list to keep track of the clients that have connected
 * and also uses a ping/pong method to monitor the client's connection state.
 * Author: James Wilkinson
 * Edge Hill University
 * 12th December 2013
 */
package Server;

import Client.GONClientInterface;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.LinkedList;


/**
 * GONServer handles the server implementation for the program.
 * It launches the server and monitors client connections. When two clients
 * connect to the server it will create a new instance of the GameOfNim class
 * which monitors the game
 * @author James Wilkinson
 */
public class GONServer extends UnicastRemoteObject implements GONServerInterface{
   
    private LinkedList<GONClientInterface> myclients;
    private static Registry registry;
    
    private static int numberOfClientsConnected;
    
    private static GONClientInterface player1 = null;
    private static GONClientInterface player2 = null;
    // Represents the pointer for the Game of nim instance
    GameOfNim gon;
    
    public GONServer() throws RemoteException {
        myclients = new LinkedList<GONClientInterface>();
    }
    
    public synchronized void regClient(GONClientInterface c) throws RemoteException {
        myclients.add(c);        
        numberOfClientsConnected++;
        System.out.println("SERVER: A client has connected. Number of clients connected: " +numberOfClientsConnected);
        
        // Assign the player1 and player2 objects to the relevant clients here.
        if(numberOfClientsConnected == 1) {
            player1 = c;
            player1.sendMsg("You are player 1. Waiting for player 2 to connect...");
            player1.sendMsg("SINGLE PLAYER WILL START IN 15 SECONDS IF NO CLIENTS CONNECT...");
        }else if(numberOfClientsConnected == 2){ // Both players at this point are connected. we can start the game!
            player2 = c;
            player2.sendMsg("You are player 2. Initialising game of nim...");;
            System.out.println("SERVER: 2 clients connected! Initialising Game of Nim...");
            gon = new GameOfNim();
        }
    }
    
    /**
     * This method initialises the single player instance of the game
     */
    public void initSinglePlayer() throws RemoteException {
        if(numberOfClientsConnected > 1) {
            System.out.println("CANNOT START SINGLE PLAYER: There is more than 1 client connected!");
            return;
        }
        
        
        System.out.println("STARTING SINGLE PLAYER...");
        player1.sendMsg("*** 15 SECONDS HAVE PASSED AND NO ADDITIONAL CLIENTS HAVE CONNECTED...");
        player1.sendMsg("*** SINGLE PLAYER STARTING");
        gon = new GameOfNim();
    }
    
    /**
     * This method will return the pointer that represents the first
     * player for the game
     * @return GONClientInterface client object representing the first player
     */
    public GONClientInterface getPlayer1Pointer() {
        return player1;
    }
    /**
     * This method will return the pointer which refers
     * to player 2 of the game
     * @return GONClientInterface client object representing the second player
     */
    public GONClientInterface getPlayer2Pointer() {
        return player2;
    }
    
    public void broadcast(String s, GONClientInterface c) throws RemoteException {
        // For debugging purposes:
        System.out.println("broadcast "+s);
        gon.onClientResponse(c, s);
    }
    
 
    public static void main(String[] args) 
    {
        int port = 1099;
        try {
            System.out.println("Starting: Server initialising...");
            //Start RMI registry (saves typing rmiregistry into command)
            try {
                registry = LocateRegistry.createRegistry(port);
                System.out.println("1. RMI registry ready on port " + port + ".");
                System.out.println("--------------------------- ");
                System.out.println("Awaiting client connection...");
            } catch (Exception e) {
                System.out.println("Exception starting RMI registry! Please ensure a server is not already runnong on this port. Exception:");
                e.getCause();
            }
        registry.rebind("NimServer", new GONServer());
        } catch (Exception e) {
            System.err.println("Problem…." +e);
        }
    }
    
    public void shutDownServer(){
        System.exit(1);
    }
}
